using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameFramework;
using GameFramework.Fsm;
using System;

namespace LS.Procedure
{
    public abstract class ProcedurePreloaderBase : GameProcedureBase
    {
        public override bool UseNativeDialog => false;
        abstract public int PreloadPriority { get; }
        /// <summary>
        /// 方便拓展不同的Proload，按照优先级自动执行
        /// </summary>
        private static GameFrameworkLinkedList<ProcedurePreloaderBase> m_ProloaderLinkedList;

        protected override void OnInit(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner)
        {
            base.OnInit(procedureOwner);
            if (m_ProloaderLinkedList == null)
            {
                m_ProloaderLinkedList = new GameFrameworkLinkedList<ProcedurePreloaderBase>();
            }
            LinkedListNode<ProcedurePreloaderBase> current = m_ProloaderLinkedList.First;
            while (current != null)
            {
                if (this.PreloadPriority < current.Value.PreloadPriority)
                {
                    break;
                }

                current = current.Next;
            }

            if (current != null)
            {
                m_ProloaderLinkedList.AddBefore(current, this);
            }
            else
            {
                m_ProloaderLinkedList.AddLast(this);
            }
        }

        protected override void OnDestroy(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner)
        {
            m_ProloaderLinkedList.Remove(this);
            base.OnDestroy(procedureOwner);
        }

        /// <summary>
        /// 切换至下一个流程，如果存在待执行的Proload则按照优先级执行，如果不存在待执行的Proload则切换到启动流程
        /// </summary>
        /// <param name="procedureOwner"></param>
        [Obsolete("Use GetNextProcedureType() to get next procedure type and use ChangeNextProcedure(Type nextProcedureType) to change next procedure.")]
        protected void ChangeNextProcedure(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner)
        {
            ChangeNextProcedure(GetNextProcedureType());
        }

        public Type GetNextProcedureType()
        {
            var currentLinkedNode = m_ProloaderLinkedList.Find(this);
            if (currentLinkedNode == null || currentLinkedNode.Next == null)
            {
                return typeof(ProcedureOpeningActions);
            }
            var nextNode = currentLinkedNode.Next;
            return nextNode.Value.GetType();
        }

        public static ProcedurePreloaderBase GetFirstProloadProcedure()
        {
            return m_ProloaderLinkedList.First.Value;
        }
    }
}